﻿#include "as_acceptor.h"
#include "epoll_watch.h"
#include "as_address.h"
#include "as_channel.h"
#include "log.h"
#include <iostream>

as::net::Acceptor::Acceptor(std::shared_ptr<EpollWatch> &epWatch, const Address &addr)
	:ep_watch_(epWatch),
	socket_(Socket::create_socket(addr.GetAF())),
	local_(addr)
{
	socket_.set_keep_alive();
	socket_.set_non_block();

	channel_ = std::make_shared<Channel>(epWatch, socket_.get_fd());
	channel_->SetReadCallback(std::bind(&as::net::Acceptor::HandleRead, this, std::placeholders::_1));
}

as::net::Acceptor::~Acceptor()
{

}

int as::net::Acceptor::bind()
{
	int ret = socket_.bind(local_);
	if (ret != 0)
	{
		LOG_ERROR << "acceptor:bind error:" << ret << " errno:" << socket_.get_last_err();
	}
	return ret;
}

int as::net::Acceptor::listen()
{
	int ret = socket_.listen();
	if (ret == 0)
	{
		channel_->EnableReadAndWriteFlag();
	}
	else
	{
		LOG_ERROR << "acceptor:listen error:" << ret << " errno:" << socket_.get_last_err();
	}
	return ret;
}

void as::net::Acceptor::close()
{
	socket_.close();
}

int as::net::Acceptor::HandleRead(TimeValue &tv)
{
	Address peerAddr;
	socket_fd newfd = socket_.accept(peerAddr);
	if (newfd == SOCKET_ERR_FD)
	{
		LOG_ERROR << "acceptor:HandleRead accpet client error";
		return -1;
	}

	if (new_conn_cb_)
	{
		new_conn_cb_(newfd, peerAddr);
		return 0;
	}

	LOG_WARNING << "acceptor:HandleRead not find new_conn_cb_";
	Socket::close(newfd);
	return -1;
}

void as::net::Acceptor::SetNewConnCallback(NewConnectCb fun)
{
	new_conn_cb_ = std::move(fun);
}

